package cn.wolfcode.car.business.service.impl;


import cn.wolfcode.car.business.domain.BpmnInfo;
import cn.wolfcode.car.business.domain.CarPackageAudit;
import cn.wolfcode.car.business.domain.ServiceItem;
import cn.wolfcode.car.business.mapper.CarPackageAuditMapper;
import cn.wolfcode.car.business.query.CarPackageAuditQuery;
import cn.wolfcode.car.business.service.IBpmnInfoService;
import cn.wolfcode.car.business.service.ICarPackageAuditService;
import cn.wolfcode.car.business.service.IServiceItemService;
import cn.wolfcode.car.common.base.page.TablePageInfo;
import cn.wolfcode.car.common.exception.BusinessException;
import cn.wolfcode.car.common.util.Convert;
import cn.wolfcode.car.shiro.ShiroUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class CarPackageAuditServiceImpl extends ServiceImpl<CarPackageAuditMapper,CarPackageAudit> implements ICarPackageAuditService {

    @Autowired
    private CarPackageAuditMapper carPackageAuditMapper;

    @Autowired
    private IBpmnInfoService bpmnInfoService;
    @Autowired
    private IServiceItemService serviceItemService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private RepositoryService repositoryService;


    @Override
    public TablePageInfo<CarPackageAudit> query(CarPackageAuditQuery qo) {
        PageHelper.startPage(qo.getPageNum(), qo.getPageSize());
        return new TablePageInfo<CarPackageAudit>(carPackageAuditMapper.selectForList(qo));
    }


    //撤销流程
    @Override
    public void cancelApply(long id) {
        CarPackageAudit carPackageAudit = this.getById(id);

        if (!CarPackageAudit.STATUS_IN_ROGRESS.equals(carPackageAudit.getStatus())) {
            throw new BusinessException("只有审核状态下，只能进行撤销！");
        }
        //审核状态取消
        UpdateWrapper<CarPackageAudit> carPackageAuditUpdateWrapper = new UpdateWrapper<>();
        carPackageAuditUpdateWrapper.eq("id",id);
        carPackageAuditUpdateWrapper.set("status",CarPackageAudit.STATUS_CANCEL);
        carPackageAuditMapper.update(null,carPackageAuditUpdateWrapper);
        //把服务单项状态改为初始化状态
        serviceItemService.changeAuditStatus(carPackageAudit.getServiceItemId(), ServiceItem.AUDITSTATUS_INIT);
        runtimeService.deleteProcessInstance(carPackageAudit.getInstanceId(),"撤销审核");
    }
    //查看流程进度
    @Override
    public InputStream processImg(long id) {
        CarPackageAudit carPackageAudit = this.getById(id);
        BpmnInfo bpmnInfo = bpmnInfoService.getById(carPackageAudit.getBpmnInfoId());
        InputStream inputStream = null;
        List<String> highLightedActivities = Collections.EMPTY_LIST;
        ProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
        BpmnModel model = repositoryService.getBpmnModel(bpmnInfo.getActProcessId());
        //如果状态为审核中还在审核拒绝，说明流程还在进行
        if (CarPackageAudit.STATUS_IN_ROGRESS.equals(carPackageAudit.getStatus())){
            Task task = taskService.createTaskQuery()
                    .processInstanceId(carPackageAudit.getInstanceId()).singleResult();
            highLightedActivities = runtimeService.getActiveActivityIds(task.getExecutionId());
        }
        inputStream = generator.generateDiagram(model, highLightedActivities,Collections.EMPTY_LIST,
                "宋体","宋体","宋体");
        return inputStream;
    }

    @Override
    @Transactional
    public void audit(long id, Integer auditStatus, String info) {
        //先判断流程
        //如果不是审核中的则抛出异常操作
        CarPackageAudit carPackageAudit = this.getById(id);
        if (carPackageAudit == null ||
                !CarPackageAudit.STATUS_IN_ROGRESS.equals(carPackageAudit.getStatus())) {
            throw new BusinessException("这是非法操作，不是审核中的状态！");
        }
        //获取用户表中名称列的属性
        String userName = ShiroUtils.getUser().getUserName();
        //判断审核人是否同意
        if (CarPackageAudit.STATUS_PASS.equals(auditStatus)) {
            info = userName + "[同意],批注意见" + info;
        }else {
            info = userName + "[拒绝],批注意见" + info;
        }

        //审核人同意备注信息
        carPackageAudit.setInfo(carPackageAudit.getInfo()+"<br/>"+info);
        //获取节点任务节点对象
        Task task = taskService.createTaskQuery().processInstanceId(carPackageAudit.getInstanceId())
                .singleResult();
        //设置审核操作中的人，进行判断同意与否的参数
        taskService.setVariable(task.getId(),"auditStatus",auditStatus);
        //设置审批备注的流程
        taskService.addComment(task.getId(),carPackageAudit.getInstanceId(),info);
        //设置执行节点的审批
        taskService.complete(task.getId());
        //获取下一个任务节点对象
        Task newTask = taskService.createTaskQuery().processInstanceId(carPackageAudit.getInstanceId())
                .singleResult();


        //判断审核状态是否为通过状态
        if ( auditStatus.equals(CarPackageAudit.STATUS_PASS)) {
            if (newTask != null){
                //流程审核记录当前审核人
                carPackageAudit.setAuditorId(Long.valueOf(newTask.getAssignee()));
                //记录当前表示审核记录表记录了当前时间
                carPackageAudit.setAuditTime(new Date());
            }else {
                //没有下一个节点流程结束
                //服务单项状态改为审核通过
                serviceItemService.changeAuditStatus(carPackageAudit.getServiceItemId(),
                        ServiceItem.AUDITSTATUS_APPROVED);
                carPackageAudit.setStatus(CarPackageAudit.STATUS_PASS);
            }
        }else {
            //审核拒绝
            //服务单项状态改为重新调整
            serviceItemService.changeAuditStatus(carPackageAudit.getServiceItemId(),
                    ServiceItem.AUDITSTATUS_REPLY);
            //流程审核记录结束，状态改为拒绝
            carPackageAudit.setStatus(CarPackageAudit.STATUS_REJECT);
        }
        carPackageAuditMapper.updateById(carPackageAudit);
    }


}
